package 算法.练习1;

import javafx.scene.layout.Priority;

import java.util.Stack;

/**
 * @author:谢君臣
 * @Date:2021/8/13-16:47
 * @version:1.0
 * @function: "(2*(3-4))*5"
 */
public class NC137 {
    public static void main(String[] args) {
        System.out.println(solve("(2*(4/2*3*4/3-4+1))*5"));
        System.out.println(solve("1-2-3"));
    }

    public static Double solve(String s) {
        // write code here
        Stack<Character> function = new Stack<>();
        Stack<Double> num = new Stack<>();
        int i = 0;
        while (i < s.length()) {
            if (s.charAt(i) < '0' || s.charAt(i) > '9') //操作符
            {
                if (s.charAt(i) == '(') function.add(s.charAt(i));
                else if (s.charAt(i) == ')') //出栈元素计算至左括号
                {
                    while (function.peek() != '(') {
                        num.add(calculate(num.pop(), num.pop(), function.pop()));
                    }
                    function.pop();  //出栈左括号
                } else { //+-*/
                    while (!function.isEmpty() && CheackPriority(function.peek(), s.charAt(i))) {  //如果栈顶优先级高,或者是/-，则先计算
                        num.add(calculate(num.pop(), num.pop(), function.pop()));
                    }
                    function.push(s.charAt(i));//将当前操作符压栈
                }
                i++;
            } else { //操作数
                double temp = 0;
                while (i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9')
                    temp = temp * 10 + (s.charAt(i++) - '0');
                num.push(temp);
            }
        }
        while (!function.isEmpty()) {
            num.add(calculate(num.pop(), num.pop(), function.pop()));
        }
        return num.pop();
    }

    private static boolean CheackPriority(Character peek, char c) {
        if ((peek == '*' || peek == '/') && (c == '+' || c == '-')) return true;  //绝对的优先级
        else if (peek == '/' && c == '*') return true; //相对优先级
        else if (peek == '-' && (c == '+' || c == '-')) return true; //相对优先级
        else return false;
    }

    private static Double calculate(Double num1, Double num2, Character fun) {
        if (fun == '*') return num1 * num2;
        else if (fun == '/') return num2 / num1;
        else if (fun == '+') return num2 + num1;
        else return num2 - num1;
    }
}
